package com.et114.modules.extend.acegi;

//import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.userdetails.UserDetails;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//import javax.servlet.ServletException;


import com.et114.components.acegi.Constants;
import com.et114.components.acegi.intercept.web.*;
import com.et114.modules.org.services.UserManager;
import com.et114.modules.org.utility.SessionUserInfo;
import com.et114.modules.org.vo.UserVo;

import org.apache.commons.beanutils.PropertyUtils;
/**
 * @author guanhw
 */
public class AwCasUserAuthenticationProcessingFilter extends org.acegisecurity.ui.cas.CasProcessingFilter {
	private UserManager				userManager	= null;
	private AwCasProviderManager	awCasProvierManager;
	private List					afterSuccessAuths;
	private Map						targetUrls;
	private long					deleym		= 2592000000L;
	private boolean					isCheckPass	= false;
	private String					checkedPass	= "toCheckPass";
	private UserVo					dtoUser		= null;
	private AwBean					bean		= new AwBean ( );

	public void setAfterSuccessAuths ( List afterSuccessAuths ) {
		if ( afterSuccessAuths != null ) {
			// Assert.notEmpty( initBeans );
			Iterator iter = afterSuccessAuths.iterator ( );
			while (iter.hasNext ( )) {
				Object currentObject = iter.next ( );
				Assert.isInstanceOf (
								ILoginSuccessfulAuthentication.class ,
								currentObject ,
								"ILoginSuccessfulAuthentication "
										+ currentObject.getClass ( ).getName ( )
										+ " must implement ILoginSuccessfulAuthentication" );
			}
		}
		this.afterSuccessAuths = afterSuccessAuths;
	}
	
	public void setUserManager ( UserManager userManager ) {
		this.userManager = userManager;
	}
	
	protected void onSuccessfulAuthentication ( HttpServletRequest request ,
			HttpServletResponse response , Authentication authResult ) {
		logger.info ( "cas auths onSuccessfulAuthentication !" ) ;
		HttpSession httpSession = request.getSession ( false );
		
		if ( httpSession != null ) {
					if ( authResult != null && authResult.getPrincipal ( ) instanceof UserDetails ) {
						try {
							// after syc
							logger.info ( "init login afterSuccessAuths beans start ..." );
							if ( afterSuccessAuths != null ) {
								for ( java.util.Iterator iter = afterSuccessAuths
										.iterator ( ) ; iter.hasNext ( ) ; ) {
									ILoginSuccessfulAuthentication la = ( ILoginSuccessfulAuthentication ) iter
											.next ( );
									la.afterSuccessfulAuthentication ( httpSession );
								}
							}
							logger.info ( "init login afterSuccessAuths beans end ..." );						
						} catch ( Exception e ) {
							logger.error ( e.getMessage ( ) , e );
						}
					}
		}
	}

	public Authentication attemptAuthentication (	HttpServletRequest httpServletRequest ) throws AuthenticationException {
		logger.info ( "cas auths Authentication attemptAuthentication !"   ) ; 
		long ct = System.currentTimeMillis ( ) ; 
		HttpSession httpSession = null;
		httpSession = httpServletRequest.getSession ( false );
		
		String ticket = httpServletRequest.getParameter ( AwConst.ACEGI_CAS_TICKET );
		if ( ticket == null ) return null;
		
		String to = httpServletRequest.getParameter ( AwConst.ACEGI_SECURITY_SUCCESS_URL_METHOD );

		

		//检查ticket
		Authentication authResult = attemptAuthentication1 ( httpServletRequest   );
		if ( authResult != null && authResult.getPrincipal ( ) instanceof UserDetails ) {
			UserDetails ud = ( UserDetails ) authResult.getPrincipal ( );
			String password = ud.getPassword ( );
			String loginName = ud.getUsername ( );

			SessionUserInfo userInfo = new SessionUserInfo( ) ; 
			

			if ( bean.getLoginType ( ) != null )  httpSession.setAttribute ( AwConst.SSO_LOGIN_TYPE_PARAM , bean.getLoginType ( ) ) ;
			if ( bean.getCode ( ) != null )  httpSession.setAttribute ( AwConst.SSO_LOGIN_TYPE_CODE , bean.getCode ( ) ) ;
			
			
			String currentSystem = Aw4UsedcarConfig.getConfig ( ).getString (  AwConst.CURRENT_SYSTEM_KEY ) ;
			if ( AwConst.SYSTEM_LAS.equalsIgnoreCase ( currentSystem ) ) {  
				dtoUser = userManager.loadUserByLoginName ( loginName ) ;
			}
			
			
			
			if ( dtoUser != null ) {
				try {
					logger.info ( "dtoUser:" + dtoUser.getUserId ( ) + ","
							+ dtoUser.getLoginName ( ) + ","
							+ dtoUser.getLastModPassTime ( ) );
					PropertyUtils.copyProperties ( userInfo , dtoUser ) ; 
				}
				catch ( Exception ex ) {
					logger.error ( ex.getMessage ( ) , ex ) ;
					return null ; 
				}
				
			}
			else {
				userInfo = userManager.getSessionUserInfoByLoginNameAndPassword ( loginName , password );
			}
			userInfo.setSessionID ( httpSession.getId ( ) );
				
			httpSession.setAttribute ( Constants.SESSION_CURRENT_USER_KEY , userInfo );

			
			if ( to == null ) {
				to = bean.getUrlTarget ( ) ; 
				if ( !getTargetUrls(  ).containsKey ( to ) ) to = null ;
			}
			
			if ( isCheckPass  ) {
				userInfo.setCheckPass ( isCheckPass ) ; 
				Date date = userInfo.getLastModPassTime ( ) ; 
				if ( date == null  ) {
					setDefaultTargetUrl (  ( ( String  )getTargetUrls(  ).get ( checkedPass )  ) ) ; 
					if ( to != null && !"".equals ( to ) ) 
						userInfo.setCheckedDefaultTargetUrl (  ( ( String  )getTargetUrls(  ).get ( to )  ) ) ;	

				}
				else {
					long cut = System.currentTimeMillis ( ) ; 
					long lastTime = date.getTime ( ) ; 
					if ( cut - lastTime >= deleym ) {
						setDefaultTargetUrl (  ( ( String  )getTargetUrls(  ).get ( checkedPass )  ) ) ; 
						if ( to != null && !"".equals ( to ) ) 
							userInfo.setCheckedDefaultTargetUrl (  ( ( String  )getTargetUrls(  ).get ( to )  ) ) ;	
					}
						
					else {
						userInfo.setCheckPassState ( true ) ;
						if ( to != null && !"".equals ( to ) ) 
							setDefaultTargetUrl (  ( ( String  )getTargetUrls(  ).get ( to )  ) ) ;	
					}
				}		
			}
			else {
				if ( to != null && !"".equals ( to ) ) 
					setDefaultTargetUrl(  ( ( String  )getTargetUrls(  ).get ( to )  ) ) ;
			}

			//check pass			
			httpSession.setAttribute ( Constants.SESSION_CURRENT_USER_KEY , userInfo );
		}
		
		logger.info ( "/***************************************************************/" ) ;
		logger.info ( "/***********CAS Authentication Total Time:"  + ( System.currentTimeMillis ( ) - ct ) + "ms*****************/"  ) ;
		logger.info ( "/***************************************************************/" ) ;
		return authResult ;
	}
	
	
	public Authentication attemptAuthentication1 ( HttpServletRequest request )
			throws AuthenticationException  {
		String username = CAS_STATEFUL_IDENTIFIER;
		String password = request.getParameter ( "ticket" );
		if ( password == null ) {
			password = "";
		}
		
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken (	username , password );
		authRequest.setDetails ( authenticationDetailsSource.buildDetails ( ( HttpServletRequest ) request ) );
		Authentication auth = awCasProvierManager .doAuthentication (  authRequest );
		dtoUser = awCasProvierManager.getCurrentUser ( ) ; 
		bean = awCasProvierManager.getBean ( ) ; 
		return auth;
	}
    
    
	public long getDeleym ( ) {
		return deleym;
	}

	public void setDeleym ( long deleym ) {
		this.deleym = deleym;
	}
	public boolean isCheckPass ( ) {
		return isCheckPass;
	}

	public void setIsCheckPass ( boolean isCheckPass ) {
		this.isCheckPass = isCheckPass;
	}

	public Map getTargetUrls ( ) {
		return targetUrls;
	}

	public void setTargetUrls ( Map targetUrls ) {
		this.targetUrls = targetUrls;
	}

	public AwCasProviderManager getAwCasProvierManager ( ) {
		return awCasProvierManager;
	}

	public void setAwCasProvierManager ( AwCasProviderManager awCasProvierManager ) {
		this.awCasProvierManager = awCasProvierManager;
	}
}
